package ru.lukyanets.transmission.protocol.model.torrent;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import ru.lukyanets.transmission.protocol.util.LocalDateTimeOfEpochDeserializer;
import ru.lukyanets.transmission.protocol.util.PiecesDeserializer;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;

/**
 * @author slukyanets
 */
@SuppressWarnings("unused")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
        "activityDate",
        "addedDate",
        "bandwidthPriority",
        "comment",
        "corruptEver",
        "creator",
        "dateCreated",
        "desiredAvailable",
        "doneDate",
        "downloadDir",
        "downloadLimit",
        "downloadLimited",
        "downloadedEver",
        "error",
        "errorString",
        "eta",
        "etaIdle",
        "fileStats",
        "files",
        "hashString",
        "haveUnchecked",
        "haveValid",
        "honorsSessionLimits",
        "id",
        "isFinished",
        "isPrivate",
        "isStalled",
        "leftUntilDone",
        "magnetLink",
        "manualAnnounceTime",
        "maxConnectedPeers",
        "metadataPercentComplete",
        "name",
        "peer-limit",
        "peers",
        "peersConnected",
        "peersFrom",
        "peersGettingFromUs",
        "peersSendingToUs",
        "percentDone",
        "pieceCount",
        "pieceSize",
        "pieces",
        "priorities",
        "queuePosition",
        "rateDownload",
        "rateUpload",
        "recheckProgress",
        "secondsDownloading",
        "secondsSeeding",
        "seedIdleLimit",
        "seedIdleMode",
        "seedRatioLimit",
        "seedRatioMode",
        "sizeWhenDone",
        "startDate",
        "status",
        "torrentFile",
        "totalSize",
        "trackerStats",
        "trackers",
        "uploadLimit",
        "uploadLimited",
        "uploadRatio",
        "uploadedEver",
        "wanted",
        "webseeds",
        "webseedsSendingToUs"
})
@Getter
@Setter
@EqualsAndHashCode(of = "id")
@ToString(of = {"id", "name"})
public class Torrent {

    @JsonProperty("id")
    private int id;
    @JsonProperty("activityDate")
    private int activityDate;
    @JsonProperty("addedDate")
    @JsonDeserialize(using = LocalDateTimeOfEpochDeserializer.class)
    private LocalDateTime addedDate;
    @JsonProperty("bandwidthPriority")
    private Priority bandwidthPriority;
    @JsonProperty("comment")
    private String comment;
    @JsonProperty("corruptEver")
    private int corruptEver;
    @JsonProperty("creator")
    private String creator;
    @JsonProperty("dateCreated")
    @JsonDeserialize(using = LocalDateTimeOfEpochDeserializer.class)
    private LocalDateTime dateCreated;
    @JsonProperty("desiredAvailable")
    private long desiredAvailable;
    @JsonProperty("doneDate")
    @JsonDeserialize(using = LocalDateTimeOfEpochDeserializer.class)
    private LocalDateTime doneDate;
    @JsonProperty("downloadDir")
    private String downloadDir;
    @JsonProperty("downloadLimit")
    private long downloadLimit;
    @JsonProperty("downloadLimited")
    private boolean downloadLimited;
    @JsonProperty("downloadedEver")
    private long downloadedEver;
    @JsonProperty("error")
    private int error;
    @JsonProperty("errorString")
    private String errorString;
    @JsonProperty("eta")
    private int eta;
    @JsonProperty("etaIdle")
    private int etaIdle;
    @JsonProperty("fileStats")
    private List<FileStat> fileStats = new ArrayList<>();
    @JsonProperty("files")
    private List<FileInfo> fileInfos = new ArrayList<>();
    @JsonProperty("hashString")
    private String hashString;
    @JsonProperty("haveUnchecked")
    private int haveUnchecked;
    @JsonProperty("haveValid")
    private long haveValid;
    @JsonProperty("honorsSessionLimits")
    private boolean honorsSessionLimits;
    @JsonProperty("isFinished")
    private boolean isFinished;
    @JsonProperty("isPrivate")
    private boolean isPrivate;
    @JsonProperty("isStalled")
    private boolean isStalled;
    @JsonProperty("leftUntilDone")
    private long leftUntilDone;
    @JsonProperty("magnetLink")
    private String magnetLink;
    @JsonProperty("manualAnnounceTime")
    @JsonDeserialize(using = LocalDateTimeOfEpochDeserializer.class)
    private LocalDateTime manualAnnounceTime;
    @JsonProperty("maxConnectedPeers")
    private int maxConnectedPeers;
    @JsonProperty("metadataPercentComplete")
    private int metadataPercentComplete;
    @JsonProperty("name")
    private String name;
    @JsonProperty("peer-limit")
    private int peerLimit;
    @JsonProperty("peers")
    private List<Object> peers = new ArrayList<>();
    @JsonProperty("peersConnected")
    private int peersConnected;
    @JsonProperty("peersFrom")
    private PeersFrom peersFrom;
    @JsonProperty("peersGettingFromUs")
    private int peersGettingFromUs;
    @JsonProperty("peersSendingToUs")
    private int peersSendingToUs;
    @JsonProperty("percentDone")
    private double percentDone;
    @JsonProperty("pieceCount")
    private int pieceCount;
    @JsonProperty("pieceSize")
    private long pieceSize;
    @JsonProperty("pieces")
    @JsonDeserialize(using = PiecesDeserializer.class)
    private BitSet pieces;
    @JsonProperty("priorities")
    private List<Priority> priorities = new ArrayList<>();
    @JsonProperty("queuePosition")
    private int queuePosition;
    @JsonProperty("rateDownload")
    private long rateDownload;
    @JsonProperty("rateUpload")
    private long rateUpload;
    @JsonProperty("recheckProgress")
    private int recheckProgress;
    @JsonProperty("secondsDownloading")
    private long secondsDownloading;
    @JsonProperty("secondsSeeding")
    private long secondsSeeding;
    @JsonProperty("seedIdleLimit")
    private int seedIdleLimit;
    @JsonProperty("seedIdleMode")
    private int seedIdleMode;
    @JsonProperty("seedRatioLimit")
    private int seedRatioLimit;
    @JsonProperty("seedRatioMode")
    private int seedRatioMode;
    @JsonProperty("sizeWhenDone")
    private long sizeWhenDone;
    @JsonProperty("startDate")
    @JsonDeserialize(using = LocalDateTimeOfEpochDeserializer.class)
    private LocalDateTime startDate;
    @JsonProperty("status")
    private TorrentStatus status;
    @JsonProperty("torrentFile")
    private String torrentFile;
    @JsonProperty("totalSize")
    private long totalSize;
    @JsonProperty("trackerStats")
    private List<TrackerStat> trackerStats = new ArrayList<>();
    @JsonProperty("trackers")
    private List<Tracker> trackers = new ArrayList<>();
    @JsonProperty("uploadLimit")
    private int uploadLimit;
    @JsonProperty("uploadLimited")
    private boolean uploadLimited;
    @JsonProperty("uploadRatio")
    private int uploadRatio;
    @JsonProperty("uploadedEver")
    private long uploadedEver;
    @JsonProperty("wanted")
    private List<Integer> wanted = new ArrayList<>();
    @JsonProperty("webseeds")
    private List<Object> webseeds = new ArrayList<>();
    @JsonProperty("webseedsSendingToUs")
    private int webseedsSendingToUs;
 }
